/**
  ******************************************************************************
  * @file    BSP_dma.c
  * @author  Silan - MC Team
  * @version 1.0.0
  * @date    2017/07/19
  * @brief   DMA related Configuration Source File
  * @details None
	* @note    None
  ******************************************************************************
  * @attention
  * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
  * AS A RESULT, SILAN MICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
  * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
  * CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
  * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
	*
  ******************************************************************************
	* Change History
	* -# 2017/07/19 | v1.0.0 | Wangjianlong | Creat file.
	*
	******************************************************************************
  */

/*******************************************************************************
 * Include file
 ******************************************************************************/
#include "SC32F58128.h"
#include "BSP_dma.h"
#include "BSP_uart.h"
#include "BSP_adc.h"

#include "api_dbg.h"

/*******************************************************************************
 * Global data for the project
 ******************************************************************************/

/*******************************************************************************
 * Local data for the current file
 ******************************************************************************/
uint16_t mg_u16SendingDatCnt;
uint16_t mg_u16SentDtatCnt;

/*******************************************************************************
 * Local prototypes function
 ******************************************************************************/

/*******************************************************************************
 * Local function for the current file
 ******************************************************************************/

/*******************************************************************************
 * Global function for the project
 ******************************************************************************/


/**
  * @brief      DMA data transfer function.
  * @param[in]  pu32SrcAdd : souce address.
  * @param[in]  pu32SrcAdd : dest address.
  * @param[in]  u16Cnt     : transfer data counter.
  * @Note       u16Cnt should be less then 16bit 
*/ 
void DMA_TranferData2UartTx(void *pu32SrcAdd, void *pu32DstAdd, uint16_t u16Cnt)
{
  if(u16Cnt > MAX_DATA_CNT)
  {
    mg_u16SendingDatCnt = u16Cnt - MAX_DATA_CNT;
    mg_u16SentDtatCnt = MAX_DATA_CNT;
    DmaDataStr[0].pSrcEndPtr = pu32SrcAdd;
    DmaDataStr[0].pDstEndPtr = pu32DstAdd;
    DmaDataStr[0].Ctrl.bit.cycle = 1;           // basic function
    DmaDataStr[0].Ctrl.bit.n_minus1 = MAX_DATA_CNT - 1;
    DmaDataStr[0].Ctrl.bit.R_power = R_POWER1;
    DmaDataStr[0].Ctrl.bit.size = 0;            // BYTE MODE
    DmaDataStr[0].Ctrl.bit.src_inc = 0;         // BYTE INC
    DmaDataStr[0].Ctrl.bit.dst_inc = 3;         // address not changed
  }
  else
  {
    mg_u16SendingDatCnt = 0;
    mg_u16SentDtatCnt = 0;
    DmaDataStr[0].pSrcEndPtr = pu32SrcAdd;
    DmaDataStr[0].pDstEndPtr = pu32DstAdd;
    DmaDataStr[0].Ctrl.bit.cycle = 1;           // basic function
    DmaDataStr[0].Ctrl.bit.n_minus1 = u16Cnt - 1;
    DmaDataStr[0].Ctrl.bit.R_power = R_POWER1;
    DmaDataStr[0].Ctrl.bit.size = 0;            // BYTE MODE
    DmaDataStr[0].Ctrl.bit.src_inc = 0;         // BYTE INC
    DmaDataStr[0].Ctrl.bit.dst_inc = 3;         // address not changed
  }
	DMA->CTRL0_b.CHNL_ENABLE = 1;
	UART_TXDMA_EN(0);
}


/**
  * @brief  DMA data transfer function.
  * @Note:  This function was called by DMA ISR, when mg_u16SendingDatCnt == 0, disable DMA interrupt.
*/ 
void SendNotSendData2UartTx(void)
{
  void * pSrcAdd;
  void * pDstAdd;

  if(mg_u16SendingDatCnt == 0)
  {
    UART_TXDMA_DIS(0);
		g_u8TxBuffState = 0;
     return;
  } 

  pSrcAdd = DmaDataStr[0].pSrcEndPtr;
  pDstAdd = DmaDataStr[0].pDstEndPtr;

  if(mg_u16SendingDatCnt > MAX_DATA_CNT)
  {
    DmaDataStr[0].pSrcEndPtr = (int8_t *)pSrcAdd + mg_u16SentDtatCnt;
    DmaDataStr[0].pDstEndPtr = (int8_t *)pDstAdd;
    DmaDataStr[0].Ctrl.bit.cycle = 1;           //basic function
    DmaDataStr[0].Ctrl.bit.n_minus1 = MAX_DATA_CNT-1;
    DmaDataStr[0].Ctrl.bit.R_power = R_POWER1;
    DmaDataStr[0].Ctrl.bit.size = 0;            //BYTE MODE
    DmaDataStr[0].Ctrl.bit.src_inc = 0;         //BYTE INC
    DmaDataStr[0].Ctrl.bit.dst_inc = 3;         //address not changed
    mg_u16SendingDatCnt = mg_u16SendingDatCnt - MAX_DATA_CNT;
    mg_u16SentDtatCnt += MAX_DATA_CNT; 
  }
  else
  {
    DmaDataStr[0].pSrcEndPtr = (int8_t *)pSrcAdd + mg_u16SentDtatCnt;
    DmaDataStr[0].pDstEndPtr = (int8_t *)pDstAdd;
    DmaDataStr[0].Ctrl.bit.cycle = 1;           //basic function
    DmaDataStr[0].Ctrl.bit.n_minus1 = mg_u16SendingDatCnt - 1;
    DmaDataStr[0].Ctrl.bit.R_power = R_POWER1;
    DmaDataStr[0].Ctrl.bit.size = 0;            //BYTE MODE
    DmaDataStr[0].Ctrl.bit.src_inc = 0;         //BYTE INC
    DmaDataStr[0].Ctrl.bit.dst_inc = 3;         //address not changed
    mg_u16SendingDatCnt =  0;
    mg_u16SentDtatCnt = 0; 
  }

	DMA->CTRL0_b.CHNL_ENABLE = 1;
	UART_TXDMA_EN(0);
}

/**
  * @brief     init all data for the function.
  * @param[in]  void : None.
  * @retval     void : None
  * @par        None
  * @par        Example:
  * This example shows how to call the function:
  * @code
  * DMA_Init();
  * @endcode
  * @Note:
*/ 
void DMA_Init(void)
{
  uint8_t  i;

  /**< Dma Data Structure Init */
  for(i = 0; i < MAX_DMA_CHANNEL; i ++)
  {
    DmaDataStr[i].pSrcEndPtr = 0;
    DmaDataStr[i].pDstEndPtr = 0;
    DmaDataStr[i].pAltSrcEndPtr = 0;
    DmaDataStr[i].pAltDstEndPtr = 0;
    DmaDataStr[i].Ctrl.all = 0;
    DmaDataStr[i].AltCtrl.all = 0;
  }

  /**< DMA Base Pointer Init */
  DMA->BASE_PTR = (uint32_t)DmaDataStr;

  /**< Clear Error Status */
  DMA->BUS_ERR = 0x0;
  DMA->CFG_ERR = 0x0;

  /**< DMA Control Register Init */
  DMA->CTRL0_b.CHNL_REQ1_MASK = 1;
  DMA->CTRL0_b.CHNL_REQ0_SEL = DBG_DMA_TRIG_SRC;

  DMA->CTRL1_b.CHNL_REQ1_MASK = 1;
  DMA->CTRL1_b.CHNL_REQ0_SEL = 0x1f;  // ERU3

  DMA->CTRL2_b.CHNL_REQ1_MASK = 1;
  DMA->CTRL2_b.CHNL_REQ0_SEL = 0x1f;  // ERU3

  DMA->CTRL3_b.CHNL_REQ1_MASK = 1;
  DMA->CTRL3_b.CHNL_REQ0_SEL = 0x1f;  // ERU3

  DmaDataStr[1].pSrcEndPtr = (uint32_t *)&ADC->ADCRESULT0;
  DmaDataStr[1].pDstEndPtr = (uint32_t *)&g_uAdSmp.AD.IUN_AD;
  DmaDataStr[1].Ctrl.bit.cycle = 2;           // auto
  DmaDataStr[1].Ctrl.bit.n_minus1 = 0;
  DmaDataStr[1].Ctrl.bit.R_power = 0;
  DmaDataStr[1].Ctrl.bit.circ = 1;            // Circle enable
  DmaDataStr[1].Ctrl.bit.size = 2;            // WORD MODE
  DmaDataStr[1].Ctrl.bit.src_inc = 3;         // NO INC
  DmaDataStr[1].Ctrl.bit.dst_inc = 3;         // NO INC

  DmaDataStr[2].pSrcEndPtr = (uint32_t *)&ADC->ADCRESULT1;
  DmaDataStr[2].pDstEndPtr = (uint32_t *)&g_uAdSmp.AD.IVN_AD;
  DmaDataStr[2].Ctrl.bit.cycle = 2;           // auto
  DmaDataStr[2].Ctrl.bit.n_minus1 = 0;
  DmaDataStr[2].Ctrl.bit.R_power = 0;
  DmaDataStr[2].Ctrl.bit.circ = 1;            // Circle enable
  DmaDataStr[2].Ctrl.bit.size = 2;            // WORD MODE
  DmaDataStr[2].Ctrl.bit.src_inc = 3;         // NO INC
  DmaDataStr[2].Ctrl.bit.dst_inc = 3;         // NO INC

  DmaDataStr[3].pSrcEndPtr = (uint32_t *)&ADC->ADCRESULT2;
  DmaDataStr[3].pDstEndPtr = (uint32_t *)&g_uAdSmp.AD.IWN_AD;
  DmaDataStr[3].Ctrl.bit.cycle = 2;           // auto
  DmaDataStr[3].Ctrl.bit.n_minus1 = 0;
  DmaDataStr[3].Ctrl.bit.R_power = 0;
  DmaDataStr[3].Ctrl.bit.circ = 1;            // Circle enable
  DmaDataStr[3].Ctrl.bit.size = 2;            // WORD MODE
  DmaDataStr[3].Ctrl.bit.src_inc = 3;         // NO INC
  DmaDataStr[3].Ctrl.bit.dst_inc = 3;         // NO INC

  DMA->DONE = 0x0;
  DMA->CTRL0_b.CHNL_DMADONE_INTREN = 1;

  /**< DMA Enable */
  DMA->CTRL0_b.CHNL_ENABLE = 1;
  DMA->CTRL1_b.CHNL_ENABLE = 1;
  DMA->CTRL2_b.CHNL_ENABLE = 1;
  DMA->CTRL3_b.CHNL_ENABLE = 1;
  DMA->CFG_b.ENABLE = 1;
}

/*---------------------------------- End of the file ---------------------------------*/
